package com.bckj.fastboot.flowable.proc.operation;

import cn.hutool.core.io.FileUtil;
import com.bckj.fastboot.core.jackson.JsonUtils;
import com.bckj.fastboot.core.operation.Operation;
import com.bckj.fastboot.core.operation.context.OpContext;
import com.bckj.fastboot.flowable.entity.FastProcess;
import com.bckj.fastboot.flowable.model.ProcCreateRequest;
import com.bckj.fastboot.flowable.model.ProcModel;
import com.bckj.fastboot.flowable.service.FastProcessService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.converter.BpmnXMLConverter;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.Process;
import org.flowable.engine.RepositoryService;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Objects;

@Slf4j
@Component
public class ProcCreateOperation implements Operation {

    @Resource
    private ProcBuildOperation procBuildOperation;
    @Resource
    private RepositoryService repositoryService;
    @Resource
    private FastProcessService fastProcessService;

    @Override
    public void execute(OpContext context) {
        var ctx = (ProcContext) context;
        ProcCreateRequest request = (ProcCreateRequest) ctx.getRequest();
        ProcModel procModel = request.getProcModel();
        var buildCtx = new ProcBuildContext();
        buildCtx.setProcModel(procModel);
        procBuildOperation.execute(buildCtx);
        Process process = buildCtx.getProcess();
        String processId = process.getId();
        BpmnModel bpmnModel = new BpmnModel();
        bpmnModel.addProcess(process);
        byte[] bpmnBytess = new BpmnXMLConverter().convertToXML(bpmnModel);
        if (Objects.equals(request.getDeployType(), 1)) {
            String filename = "/tmp/flowable-deployment/" + processId + ".bpmn20.xml";
            log.debug("部署时的模型文件：{}", filename);
            FileUtil.writeBytes(bpmnBytess, filename);
            repositoryService.createDeployment()
                    .addBpmnModel("%s.bpmn20.xml".formatted(processId), bpmnModel).deploy();
        }
        String procModelJson = JsonUtils.toJsonStr(procModel);
        FastProcess fastProcess = new FastProcess();
        fastProcess.setProcessId(processId);
        fastProcess.setProcessName(process.getName());
        fastProcess.setContent(new String(bpmnBytess));
        fastProcess.setProcModel(procModelJson);
        fastProcessService.save(fastProcess);
        FastProcess exist = fastProcessService.lambdaQuery()
                .eq(FastProcess::getProcessId, processId)
                .select(FastProcess::getId, FastProcess::getVersion).one();
        if (exist != null) {
            fastProcess.setId(exist.getId());
            fastProcess.setVersion(exist.getVersion() + 1);
            fastProcess.setUpdateTime(LocalDateTime.now());
            fastProcessService.updateById(fastProcess);
        } else {
            fastProcessService.save(fastProcess);
        }
    }
}
